#include <iostream>
#include <unordered_map>
#include <vector>
#include <functional>
#include <memory>
#include <mutex>

using namespace std;

/// @brief 总线模型
/// @tparam EventType
template<typename EventType>
class EventBus {
public:
	// 添加订阅频道
	size_t Subscribe(function<void(const EventType &)> handler, const uint8_t channel = 0) {
		lock_guard<mutex> lock(m_mutex);
		subscribers.push_back(handler);
		return subscribers.size() - 1;
	};

	bool Unsubscribe(size_t token) {
		lock_guard<mutex> lock(m_mutex);
		if (token >= subscribers.size()) return false;
		subscribers[token] = nullptr;
		return true;
	}

	void Publish(const EventType &event) {
		vector<function<void(const EventType &)>> activeHandlers;
		{
			lock_guard<mutex> lock(m_mutex);
			activeHandlers.reserve(subscribers.size());
			for (const auto &handler: subscribers) {
				if (handler) activeHandlers.push_back(handler);
			}
		}
		for (const auto &handler: activeHandlers) {
			handler(event);
		}
	}

private:
	vector<function<void(const EventType &)>> subscribers; // 订阅者列表
	mutex                                     m_mutex;
};

// g++ -std=c++11 event_bus_simple.cpp -o event_bus_simple.exe
int main() {
	struct MessageEvent {
		string content;
		int    senderId;
	};

	EventBus<MessageEvent> bus;

	// 订阅者1
	auto token1 = bus.Subscribe([](const MessageEvent &event) {
		//
		cout << "Subscriber 1: Received message - " << event.content << endl;
	});

	// 订阅者2
	int  count  = 0;
	auto token2 = bus.Subscribe([&count](const MessageEvent &event) {
		count++;
		cout << "Subscriber 2: Total message - " << count << endl;
	});

	// 发布事件
	MessageEvent event = {"Hello EventBus!", 123};
	bus.Publish(event);

	// 取消订阅
	bus.Unsubscribe(token2);

	// 再次发布
	bus.Publish({"Second message", 456});
	return 0;
}
